﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;

namespace project_forgotten_tuba
{
    public static class BinarySerializer
    {
        public static TData DeserializeFromByteArray<TData>(byte[] settings)
        {
            using (var stream = new MemoryStream(settings))
            {
                var formatter = new BinaryFormatter();
                stream.Seek(0, SeekOrigin.Begin);
                TData retdata = (TData)formatter.Deserialize(stream);

                return retdata;
            }

        }

        public static byte[] SerializeToByteArray<TData>(TData settings)
        {
            using (var stream = new MemoryStream())
            {
                //exception here probably means something wasnt marked as serializable
                var formatter = new BinaryFormatter();
                formatter.Serialize(stream, settings);
                stream.Flush();
                stream.Position = 0;
                byte[] retbytearray = stream.ToArray();

                return retbytearray;
            }
        }

        public static bool IsSerializable<TData>(TData settings)
        {
            try
            {
                byte[] serializedobject = SerializeToByteArray<TData>(settings);
                TData deserializedobject = DeserializeFromByteArray<TData>(serializedobject);
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }
    }

    public static class ByteArrayCompressor
    {
        public static byte[] Compress(byte[] input)
        {
            byte[] output;
            using (MemoryStream ms = new MemoryStream())
            {
                using (GZipStream gs = new GZipStream(ms, CompressionMode.Compress))
                {
                    gs.Write(input, 0, input.Length);
                    gs.Close();
                    output = ms.ToArray();
                }
                ms.Close();
            }

            return output;
        }

        public static byte[] Decompress(byte[] input)
        {
            List<byte> output = new List<byte>();
            using (MemoryStream ms = new MemoryStream(input))
            {
                using (GZipStream gs = new GZipStream(ms, CompressionMode.Decompress))
                {
                    int readByte = gs.ReadByte();
                    while (readByte != -1)
                    {
                        output.Add((byte)readByte);
                        readByte = gs.ReadByte();
                    }
                    gs.Close();
                }
                ms.Close();
            }

            return output.ToArray();
        }
    }
}
